package me.android.library.utils.android;

import android.annotation.SuppressLint;
import android.content.ContentResolver;
import android.content.ContentValues;
import android.content.Context;
import android.database.Cursor;
import android.net.Uri;
import android.os.Build;
import android.provider.DocumentsContract;
import android.provider.MediaStore;

import java.io.Closeable;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Objects;

import lombok.experimental.UtilityClass;
import lombok.extern.slf4j.Slf4j;
import mylab.utils.common.StringUtil;


@Slf4j
@UtilityClass
public class UriUtil {

    @SuppressLint("Range")
    public Uri getImageContentUri(File imageFile) {
        Context context = ContextUtil.getAppContext();
        String filePath = imageFile.getAbsolutePath();
        Uri uri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
        String[] projection = new String[]{MediaStore.Images.Media._ID};
        String selection = MediaStore.Images.Media.DATA + "=? ";
        String[] selectionArgs = new String[]{filePath};
        try (Cursor cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null)) {
            if (cursor != null && cursor.moveToFirst()) {
                int id = cursor.getInt(cursor.getColumnIndex(MediaStore.MediaColumns._ID));
                Uri baseUri = Uri.parse("content://media/external/images/media");
                return Uri.withAppendedPath(baseUri, "" + id);
            } else {
                if (imageFile.exists()) {
                    ContentValues values = new ContentValues();
                    values.put(MediaStore.Images.Media.DATA, filePath);
                    return context.getContentResolver().insert(MediaStore.Images.Media.EXTERNAL_CONTENT_URI, values);
                } else {
                    return null;
                }
            }
        }
    }

    /**
     * 将 Uri 转换为 File 对象（兼容多种 Uri 类型和 Android 版本）
     *
     * @param uri 要转换的 Uri
     * @return 对应的 File 对象，若无法转换则返回 null
     */
    public static File uriToFile(Uri uri) {
        if (uri == null) return null;

        // 方案一：尝试直接从 Uri 获取路径（针对 file:// 类型的 Uri）
        if ("file".equalsIgnoreCase(uri.getScheme())) {
            return new File(Objects.requireNonNull(uri.getPath()));
        }

        // 方案二：处理 content:// 类型的 Uri
        if ("content".equalsIgnoreCase(uri.getScheme())) {
            // Android 10+ 推荐使用 DocumentFile
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
                return createFileFromUri(uri);
            }

            // 针对 MediaStore 和 DownloadsProvider 的 Uri
            if (isMediaDocument(uri) || isDownloadsDocument(uri)) {
                String documentId = DocumentsContract.getDocumentId(uri);
                String[] split = documentId.split(":");
                String type = split[0];
                String id = split.length > 1 ? split[1] : documentId;

                // 重新构建查询 Uri
                Uri contentUri;
                if ("image".equals(type)) {
                    contentUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI;
                } else if ("video".equals(type)) {
                    contentUri = MediaStore.Video.Media.EXTERNAL_CONTENT_URI;
                } else if ("audio".equals(type)) {
                    contentUri = MediaStore.Audio.Media.EXTERNAL_CONTENT_URI;
                } else {
                    contentUri = MediaStore.Files.getContentUri("external");
                }

                String selection = "_id=?";
                String[] selectionArgs = new String[]{id};

                return getFileFromContentUri(contentUri, selection, selectionArgs);
            }

            // 其他 content Uri，尝试直接查询路径
            return getFileFromContentUri(uri, null, null);
        }

        return null;
    }

    /**
     * 从 Content Uri 中获取文件（针对 MediaStore 类型的 Uri）
     */
    private static File getFileFromContentUri(Uri uri, String selection, String[] selectionArgs) {
        Cursor cursor = null;
        final String column = "_data";
        final String[] projection = {column};
        Context context = ContextUtil.getAppContext();

        try {
            cursor = context.getContentResolver().query(uri, projection, selection, selectionArgs, null);
            if (cursor != null && cursor.moveToFirst()) {
                final int index = cursor.getColumnIndexOrThrow(column);
                String filePath = cursor.getString(index);
                if (filePath != null) {
                    return new File(filePath);
                }
            }
        } catch (Exception ignored) {
        } finally {
            if (cursor != null) {
                cursor.close();
            }
        }

        // 如果无法直接获取路径，则创建临时文件
        return createFileFromUri(uri);
    }

    /**
     * 从 Uri 创建临时文件（适用于无法直接获取路径的情况）
     */
    private static File createFileFromUri(Uri uri) {
        InputStream inputStream = null;
        FileOutputStream outputStream = null;
        File tempFile = null;

        Context context = ContextUtil.getAppContext();
        try {
            // 创建临时文件
            tempFile = File.createTempFile(
                    "temp_" + System.currentTimeMillis(),
                    getFileExtension(uri),
                    context.getCacheDir()
            );

            // 复制文件内容
            ContentResolver contentResolver = context.getContentResolver();
            inputStream = contentResolver.openInputStream(uri);
            outputStream = new FileOutputStream(tempFile);

            if (inputStream != null) {
                copyStream(inputStream, outputStream);
                return tempFile;
            }
        } catch (IOException e) {
            log.warn("createFileFromUri error", e);
        } finally {
            // 关闭流
            closeQuietly(inputStream);
            closeQuietly(outputStream);
        }

        return null;
    }

    /**
     * 复制输入流到输出流
     */
    private static void copyStream(InputStream input, OutputStream output) throws IOException {
        byte[] buffer = new byte[4096];
        int bytesRead;
        while ((bytesRead = input.read(buffer)) != -1) {
            output.write(buffer, 0, bytesRead);
        }
    }

    /**
     * 安静地关闭流（忽略异常）
     */
    private static void closeQuietly(Closeable closeable) {
        if (closeable != null) {
            try {
                closeable.close();
            } catch (IOException e) {
                // 忽略
            }
        }
    }

    /**
     * 获取文件扩展名
     */
    private static String getFileExtension(Uri uri) {
        ContentResolver contentResolver = ContextUtil.getContentResolver();
        String mimeType = contentResolver.getType(uri);
        if (mimeType != null) {
            // 尝试从 MIME 类型获取扩展名
            switch (mimeType) {
                case "image/jpeg" -> {
                    return ".jpg";
                }
                case "image/png" -> {
                    return ".png";
                }
                case "video/mp4" -> {
                    return ".mp4";
                }
            }
            // 可以添加更多 MIME 类型映射...
        }

        // 尝试从 Uri 路径获取扩展名
        String path = uri.getPath();
        if (path != null) {
            int dotIndex = path.lastIndexOf('.');
            if (dotIndex > 0) {
                return path.substring(dotIndex);
            }
        }

        // 默认返回空扩展名
        return StringUtil.EMPTY;
    }

    /**
     * 判断是否为 MediaStore 文档
     */
    private static boolean isMediaDocument(Uri uri) {
        return "com.android.providers.media.documents".equals(uri.getAuthority());
    }

    /**
     * 判断是否为 DownloadsProvider 文档
     */
    private static boolean isDownloadsDocument(Uri uri) {
        return "com.android.providers.downloads.documents".equals(uri.getAuthority());
    }

}

